home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 2010 April / PCWorld0410.iso / redakcyjne / programy / eM CLient 2.0.5952.0 Beta / setup.msi / eMClient.cab / ManualChmFile / skinsupport / madcapeffects.js < prev    next >
Text File  |  2009-09-08  |  23KB  |  847 lines

  1. // {{MadCap}} //////////////////////////////////////////////////////////////////
  2. // Copyright: MadCap Software, Inc - www.madcapsoftware.com ////////////////////
  3. ////////////////////////////////////////////////////////////////////////////////
  4. // <version>3.0.0.0</version>
  5. ////////////////////////////////////////////////////////////////////////////////
  6.  
  7. var gPopupObj           = null;
  8. var gPopupBGObj         = null;
  9. var gJustPopped         = false;
  10.  
  11. var gFadeID             = 0;
  12.  
  13. var gTextPopupBody      = null;
  14. var gTextPopupBodyBG    = null;
  15.  
  16. var gImgNode            = null;
  17.  
  18. function FMCImageSwap( img, swapType )
  19. {
  20.     var state    = FMCGetMCAttribute( img, "MadCap:state" );
  21.     
  22.     switch ( swapType )
  23.     {
  24.         case "swap":
  25.             var src        = img.src;
  26.             var altsrc2    = FMCGetMCAttribute( img, "MadCap:altsrc2" );
  27.             
  28.             if ( !altsrc2 )
  29.             {
  30.                 altsrc2 = FMCGetMCAttribute( img, "MadCap:altsrc" );
  31.             }
  32.             
  33.             img.src = altsrc2;
  34.             img.setAttribute( "MadCap:altsrc2", src );
  35.             img.setAttribute( "MadCap:state", (state == null || state == "close") ? "open" : "close" );
  36.             
  37.             break;
  38.             
  39.         case "open":
  40.             if ( state != swapType )
  41.             {
  42.                 FMCImageSwap( img, "swap" );
  43.             }
  44.             
  45.             break;
  46.             
  47.         case "close":
  48.             if ( state == "open" )
  49.             {
  50.                 FMCImageSwap( img, "swap" );
  51.             }
  52.             
  53.             break;
  54.     }
  55. }
  56.  
  57. function FMCExpandAll( swapType )
  58. {
  59.     var nodes   = FMCGetElementsByAttribute( document, "MadCap:targetName", "*" );
  60.     
  61.     for ( var i = 0; i < nodes.length; i++ )
  62.     {
  63.         nodes[i].style.display = (swapType == "open") ? "" : "none";
  64.     }
  65.     
  66.     nodes = FMCGetElementsByClassRoot( document, "MCTogglerIcon" );
  67.     
  68.     for ( var i = 0; i < nodes.length; i++ )
  69.     {
  70.         FMCImageSwap( nodes[i], swapType );
  71.     }
  72.     
  73.     nodes = FMCGetElementsByClassRoot( document, "MCExpandingBody" );
  74.     
  75.     for ( var i = 0; i < nodes.length; i++ )
  76.     {
  77.         nodes[i].style.display = (swapType == "open") ? "" : "none";
  78.     }
  79.     
  80.     nodes = FMCGetElementsByClassRoot( document, "MCExpandingIcon" );
  81.     
  82.     for ( var i = 0; i < nodes.length; i++ )
  83.     {
  84.         FMCImageSwap( nodes[i], swapType );
  85.     }
  86.     
  87.     nodes = FMCGetElementsByClassRoot( document, "MCDropDownBody" );
  88.     
  89.     for ( var i = 0; i < nodes.length; i++ )
  90.     {
  91.         nodes[i].style.display = (swapType == "open") ? "" : "none";
  92.     }
  93.     
  94.     nodes = FMCGetElementsByClassRoot( document, "MCDropDownIcon" );
  95.     
  96.     for ( var i = 0; i < nodes.length; i++ )
  97.     {
  98.         FMCImageSwap( nodes[i], swapType );
  99.     }
  100. }
  101.  
  102. function FMCDropDown( node )
  103. {
  104.     // Find head node
  105.     
  106.     var headNode    = node;
  107.     
  108.     while ( !FMCContainsClassRoot( headNode.className, "MCDropDown", "GlossaryPageEntry" ) )
  109.     {
  110.         headNode = headNode.parentNode;
  111.     }
  112.     
  113.     // Toggle the icon
  114.     
  115.     var imgNodes    = node.getElementsByTagName( "img" );
  116.     
  117.     for ( var i = 0; i < imgNodes.length; i++ )
  118.     {
  119.         var imgNode = imgNodes[i];
  120.         
  121.         if ( FMCContainsClassRoot( imgNode.className, "MCDropDownIcon" ) )
  122.         {
  123.             FMCImageSwap( imgNode, "swap" );
  124.             
  125.             break;
  126.         }
  127.     }
  128.     
  129.     // Hide/unhide the body
  130.     
  131.     var id              = node.id.substring( "MCDropDownHotSpot_".length, node.id.length );
  132.     var dropDownBody    = document.getElementById( "MCDropDownBody_" + id );
  133.     
  134.     dropDownBody.style.display = (dropDownBody.style.display == "none") ? "" : "none";
  135. }
  136.  
  137. function FMCExpand( node )
  138. {
  139.     // Find top node
  140.     
  141.     while ( !FMCContainsClassRoot( node.className, "MCExpanding" ) )
  142.     {
  143.         node = node.parentNode;
  144.     }
  145.     
  146.     var nodes       = node.childNodes;
  147.     var imgNodes    = node.getElementsByTagName( "img" );
  148.     
  149.     // Toggle the icon
  150.     
  151.     for ( var i = 0; i < imgNodes.length; i++ )
  152.     {
  153.         var imgNode = imgNodes[i];
  154.         
  155.         if ( FMCContainsClassRoot( imgNode.className, "MCExpandingIcon" ) )
  156.         {
  157.             FMCImageSwap( imgNode, "swap" );
  158.             
  159.             break;
  160.         }
  161.     }
  162.     
  163.     // Hide/unhide the body
  164.     
  165.     var expandingBody;
  166.     
  167.     for ( i = 0; i < nodes.length; i++ )
  168.     {
  169.         var node = nodes[i];
  170.         
  171.         if ( FMCContainsClassRoot( node.className, "MCExpandingBody" ) )
  172.         {
  173.             expandingBody = node;
  174.             break;
  175.         }
  176.     }
  177.     
  178.     expandingBody.style.display = (expandingBody.style.display == "none") ? "" : "none";
  179. }
  180.  
  181. function FMCPopup( e, node )
  182. {
  183.     // Don't continue if something is already popped up
  184.     
  185.     if ( gPopupObj )
  186.     {
  187.         return;
  188.     }
  189.     
  190.     if ( !e )
  191.     {
  192.         e = window.event;
  193.     }
  194.     
  195.     if ( FMCInPreviewMode() && document.documentElement.innerHTML.indexOf( "<!-- saved from url" ) != -1 )
  196.     {
  197.         var span    = document.getElementById( "MCTopicPopupWarning" );
  198.         
  199.         if ( !span )
  200.         {
  201.             span = document.createElement( "span" );
  202.             span.id = "MCTopicPopupWarning";
  203.             span.className = "MCTextPopupBody";
  204.             span.style.display = "none";
  205.             span.appendChild( document.createTextNode( "Topic popups can not be displayed when Insert Mark of the Web is enabled in the target." ) );
  206.             
  207.             document.body.appendChild( span );
  208.         }
  209.         
  210.         gTextPopupBody = span;
  211.         
  212.         FMCShowTextPopup( e );
  213.         
  214.         return;
  215.     }
  216.     
  217.     // Toggle the icon
  218.     
  219.     var imgNodes    = node.getElementsByTagName( "img" );
  220.     
  221.     for ( var i = 0; i < imgNodes.length; i++ )
  222.     {
  223.         var imgNode = imgNodes[i];
  224.         
  225.         if ( FMCContainsClassRoot( imgNode.className, "MCExpandingIcon" ) )
  226.         {
  227.             FMCImageSwap( imgNode, "swap" );
  228.             gImgNode = imgNode;
  229.             
  230.             break;
  231.         }
  232.     }
  233.     
  234.     // Find iframe node
  235.     
  236.     var popupBody;
  237.     
  238.     if ( node.nodeName == "AREA" )
  239.     {
  240.         var iframeName  = FMCGetMCAttribute( node, "MadCap:iframeName" );
  241.         var iframes     = document.getElementsByTagName( "iframe" );
  242.         
  243.         for ( var i = 0; i < iframes.length; i++ )
  244.         {
  245.             var iframe  = iframes[i];
  246.             
  247.             if ( iframe.name == iframeName )
  248.             {
  249.                 popupBody = iframe;
  250.                 break;
  251.             }
  252.         }
  253.     }
  254.     else
  255.     {
  256.         while ( !FMCContainsClassRoot( node.className, "MCPopup" ) )
  257.         {
  258.             node = node.parentNode;
  259.         }
  260.         
  261.         var nodes   = node.childNodes;
  262.         
  263.         for ( i = 0; i < nodes.length; i++ )
  264.         {
  265.             var node    = nodes[i];
  266.             
  267.             if ( FMCContainsClassRoot( node.className, "MCPopupBody" ) )
  268.             {
  269.                 popupBody = node;
  270.                 break;
  271.             }
  272.         }
  273.     }
  274.     
  275.     // Hide/unhide the body
  276.     
  277.     if ( popupBody.style.display == "none" )
  278.     {
  279.         gJustPopped = true;
  280.         
  281.         popupBody.MCClientX = e.clientX;
  282.         popupBody.MCClientY = e.clientY;
  283.  
  284.         // Safari
  285.  
  286.         if ( FMCIsSafari() )
  287.         {
  288.             var src    = FMCGetMCAttribute( popupBody, "MadCap:src" );
  289.             
  290.             if ( popupBody.src == "" || popupBody.src.EndsWith( "Blank.htm", false ) )
  291.             {
  292.                 popupBody.src = src;
  293.             }
  294.             
  295.             if ( src.substring( 0, 4 ) == "http" )
  296.             {
  297.                 FMCIFrameOnload( popupBody ); // Safari bug: if src of iframe is external, onload event doesn't get triggered so trigger it manually.
  298.             }
  299.             else
  300.             {
  301.                 popupBody.style.display = ""; // Triggers onload event
  302.             }
  303.  
  304.             return;
  305.         }
  306.  
  307.         //
  308.  
  309.         if ( popupBody.src == "" || popupBody.src.EndsWith( "Blank.htm", false ) )
  310.         {
  311.             popupBody.src = FMCGetMCAttribute( popupBody, "MadCap:src" );
  312.         }
  313.         else
  314.         {
  315.             FMCIFrameOnload( popupBody );
  316.         }
  317.     }
  318. }
  319.  
  320. function FMCIFrameOnload( popupBody )
  321. {
  322.     if ( popupBody.src == "" || popupBody.src.EndsWith( "Blank.htm", false ) )
  323.     {
  324.         return;
  325.     }
  326.     else if ( popupBody.style.display == "" && !FMCIsSafari() ) // Mozilla: When the popup is clicked, the onload gets called twice, so return the second time.
  327.     {
  328.         return;
  329.     }
  330.  
  331.     popupBody.style.display = "";
  332.     FMCSetPopupSize( popupBody );
  333.     
  334.     var clientX                = popupBody.MCClientX;
  335.     var clientY                = popupBody.MCClientY;
  336.     var absolutePosition    = FMCGetPosition( popupBody.offsetParent );
  337.     var absoluteTop            = absolutePosition[0];
  338.     var absoluteLeft        = absolutePosition[1];
  339.     var newTop                = 0;
  340.     var newLeft                = 0;
  341.     
  342.     // "+ 5" is to account for width of popup shadow.
  343.     
  344.     if ( clientY + parseInt( popupBody.style.height ) + 5 > FMCGetClientHeight( window, false ) )
  345.     {
  346.         newTop = FMCGetScrollTop( window ) + FMCGetClientHeight( window, false ) - parseInt( popupBody.style.height ) - 5;
  347.     }
  348.     else
  349.     {
  350.         newTop = clientY + FMCGetScrollTop( window );
  351.     }
  352.     
  353.     newTop -= absoluteTop;
  354.     popupBody.style.top = newTop + "px";
  355.     
  356.     if ( clientX + parseInt( popupBody.style.width ) + 5 > FMCGetClientWidth( window, false ) )
  357.     {
  358.         newLeft = FMCGetScrollLeft( window ) + FMCGetClientWidth( window, false ) - parseInt( popupBody.style.width ) - 5;
  359.     }
  360.     else
  361.     {
  362.         newLeft = clientX + FMCGetScrollLeft( window );
  363.     }
  364.     
  365.     newLeft -= absoluteLeft;
  366.     popupBody.style.left = newLeft + "px";
  367.     
  368.     // Set up background
  369.     
  370.     var popupBodyBG = document.createElement( "span" );
  371.     
  372.     popupBodyBG.className = "MCPopupBodyBG";
  373.     popupBodyBG.style.top = newTop + 5 + "px";
  374.     popupBodyBG.style.left = newLeft + 5 + "px";
  375.     popupBodyBG.style.width = parseInt( popupBody.offsetWidth ) + "px";
  376.     popupBodyBG.style.height = parseInt( popupBody.offsetHeight ) + "px";
  377.     
  378.     popupBody.parentNode.appendChild( popupBodyBG );
  379.     gPopupObj = popupBody;
  380.     gPopupBGObj = popupBodyBG;
  381.     
  382.     //
  383.     
  384.     gFadeID = setInterval( "FMCFade()", 10 );
  385. }
  386.  
  387. function FMCSetPopupSize( popupNode )
  388. {
  389.     if ( popupNode.style.width != "auto" || popupNode.style.height != "auto" )
  390.     {
  391.         return;
  392.     }
  393.     
  394.     //
  395.     
  396.     var clientWidth     = FMCGetClientWidth( window, false );
  397.     var clientHeight    = FMCGetClientHeight( window, false );
  398.     var stepSize        = 10;
  399.     var hwRatio         = clientHeight / clientWidth;
  400.     var popupFrame      = frames[popupNode.name];
  401.     var maxX            = clientWidth * 0.618034;
  402.     var i               = 0;
  403.     
  404.     // Debug
  405.     //window.status += document.body.clientHeight + ", " + document.body.offsetHeight + ", " + document.body.scrollHeight + ", " + document.body.scrollTop;
  406.     //window.status += " : " + document.documentElement.clientHeight + ", " + document.documentElement.offsetHeight + ", " + document.documentElement.scrollHeight + ", " + document.documentElement.scrollTop;
  407.     
  408.     // Safari
  409.     
  410.     if ( FMCIsSafari() )
  411.     {
  412.         popupNode.style.width = maxX + "px";
  413.         popupNode.style.height = (maxX * hwRatio) + "px";
  414.         
  415.         return;
  416.     }
  417.     
  418.     //
  419.     
  420.     try
  421.     {
  422.         var popupDocument   = popupFrame.document; // This will throw an exception in IE.
  423.         
  424.         FMCGetScrollHeight( popupFrame.window );   // This will throw an exception in Mozilla.
  425.     }
  426.     catch ( err )
  427.     {
  428.         popupNode.style.width = maxX + "px";
  429.         popupNode.style.height = (maxX * hwRatio) + "px";
  430.         
  431.         return;
  432.     }
  433.     
  434.     while ( true )
  435.     {
  436.         popupNode.style.width = maxX - (i * stepSize) + "px";
  437.         popupNode.style.height = (maxX - (i * stepSize)) * hwRatio + "px";
  438.         
  439.         if ( FMCGetScrollHeight( popupFrame.window ) > FMCGetClientHeight( popupFrame.window, false ) ||
  440.              FMCGetScrollWidth( popupFrame.window ) > FMCGetClientWidth( popupFrame.window, false ) )
  441.         {
  442.             popupNode.style.width = maxX - ((i - 1) * stepSize) + "px";
  443.             popupNode.style.height = (maxX - ((i - 1) * stepSize)) * hwRatio + "px";
  444.             
  445.             break;
  446.         }
  447.         
  448.         i++;
  449.     }
  450. }
  451.  
  452. function GetHelpControlLinks( node, callbackFunc, callbackArgs )
  453. {
  454.     var linkMap            = new Array();
  455.     var inPreviewMode    = FMCInPreviewMode();
  456.     var rootFrame        = FMCGetRootFrame();
  457.  
  458.     if ( !inPreviewMode && rootFrame.gHelpSystem.IsMerged() && FMCGetMCAttribute( node, "MadCap:indexKeywords" ) != null )
  459.     {
  460.         function OnInit()
  461.         {
  462.             var indexKeywords   = FMCGetMCAttribute( node, "MadCap:indexKeywords" ).replace( "\\;", "%%%%%" );
  463.             
  464.             if ( indexKeywords == "" )
  465.             {
  466.                 callbackFunc( linkMap, callbackArgs );
  467.             }
  468.             
  469.             var keywords        = indexKeywords.split( ";" );
  470.             
  471.             for ( var i = 0; i < keywords.length; i++ )
  472.             {
  473.                 keywords[i] = keywords[i].replace( "%%%%%", ";" );
  474.                 
  475.                 var currKeyword = keywords[i].replace( "\\:", "%%%%%" );
  476.                 var keywordPath = currKeyword.split( ":" );
  477.                 var level       = keywordPath.length - 1;
  478.                 var indexKey    = level + "_" + keywordPath[level].replace( "%%%%%", ":" );
  479.                 
  480.                 var currLinkMap = indexFrame.gLinkMap.GetItem( indexKey.toLowerCase() );
  481.                 
  482.                 // currLinkMap may be blank if keywords[i] isn't found in index XML file (user may have deleted keyword after associating it with a K-Link)
  483.                 
  484.                 if ( currLinkMap )
  485.                 {
  486.                     for ( var key in currLinkMap.GetKeys() )
  487.                     {
  488.                         linkMap[linkMap.length] = key + "|" + currLinkMap.GetItem( key );
  489.                     }
  490.                 }
  491.             }
  492.  
  493.             callbackFunc( linkMap, callbackArgs );
  494.         }
  495.  
  496.         var indexFrame  = rootFrame.frames["navigation"].frames["index"];
  497.         
  498.         indexFrame.Init( OnInit );
  499.  
  500.         return;
  501.     }
  502.     else if ( !inPreviewMode && rootFrame.gHelpSystem.IsMerged() && FMCGetMCAttribute( node, "MadCap:concepts" ) != null )
  503.     {
  504.         var concepts    = FMCGetMCAttribute( node, "MadCap:concepts" );
  505.         var args        = { callbackFunc: callbackFunc, callbackArgs: callbackArgs };
  506.         
  507.         rootFrame.gHelpSystem.GetConceptsLinks( concepts, OnGetConceptsLinks, args );
  508.         
  509.         return;
  510.     }
  511.     else if ( FMCGetMCAttribute( node, "MadCap:topics" ) != null )
  512.     {
  513.         var topics  = FMCGetMCAttribute( node, "MadCap:topics" ).split( "||" );
  514.         
  515.         if ( topics == "" )
  516.         {
  517.             callbackFunc( linkMap, callbackArgs );
  518.         }
  519.         
  520.         for ( var i = 0; i < topics.length; i++ )
  521.         {
  522.             linkMap[linkMap.length] = topics[i];
  523.         }
  524.     }
  525.  
  526.     callbackFunc( linkMap, callbackArgs );
  527. }
  528.  
  529. function OnGetConceptsLinks( links, args )
  530. {
  531.     var callbackFunc    = args.callbackFunc;
  532.     var callbackArgs    = args.callbackArgs;
  533.     
  534.     callbackFunc( links, callbackArgs );
  535. }
  536.  
  537. function FMCTextPopup( e, node )
  538. {
  539.     // Don't continue if something is already popped up
  540.     
  541.     if ( gPopupObj )
  542.     {
  543.         return;
  544.     }
  545.     
  546.     if ( !e )
  547.     {
  548.         e = window.event;
  549.     }
  550.     
  551.     // Find top node
  552.     
  553.     while ( !FMCContainsClassRoot( node.className, "MCTextPopup" ) )
  554.     {
  555.         node = node.parentNode;
  556.     }
  557.     
  558.     // Toggle the icon
  559.     
  560.     var imgNodes    = node.getElementsByTagName( "img" );
  561.     
  562.     for ( var i = 0; i < imgNodes.length; i++ )
  563.     {
  564.         var imgNode = imgNodes[i];
  565.         
  566.         if ( FMCContainsClassRoot( imgNode.className, "MCExpandingIcon" ) )
  567.         {
  568.             FMCImageSwap( imgNode, "swap" );
  569.             gImgNode = imgNode;
  570.             
  571.             break;
  572.         }
  573.     }
  574.     
  575.     // Hide/unhide the body
  576.     
  577.     var nodes   = node.childNodes;
  578.     
  579.     for ( i = 0; i < nodes.length; i++ )
  580.     {
  581.         var node = nodes[i];
  582.         
  583.         if ( FMCContainsClassRoot( node.className, "MCTextPopupBody" ) )
  584.         {
  585.             gTextPopupBody = node;
  586.             break;
  587.         }
  588.     }
  589.     
  590.     FMCShowTextPopup( e );
  591. }
  592.  
  593. function FMCShowTextPopup( e )
  594. {
  595.     if ( gTextPopupBody.style.display == "none" )
  596.     {
  597.         if ( gTextPopupBody.childNodes.length == 0 )
  598.         {
  599.             gTextPopupBody.appendChild( document.createTextNode( "(No data to display)") );
  600.         }
  601.         
  602.         gTextPopupBody.style.display = "";
  603.         
  604.         FMCSetTextPopupSize( gTextPopupBody );
  605.         
  606.         // "+ 5" is to account for width of popup shadow.
  607.         
  608.         if ( FMCGetClientY( window, e ) + gTextPopupBody.offsetHeight + 5 > FMCGetClientHeight( window, false ) )
  609.         {
  610.             gTextPopupBody.style.top = FMCGetScrollTop( window ) + FMCGetClientHeight( window, false ) - gTextPopupBody.offsetHeight - 5 + "px";
  611.         }
  612.         else
  613.         {
  614.             gTextPopupBody.style.top = FMCGetPageY( window, e ) + "px";
  615.         }
  616.         
  617.         if ( FMCGetClientX( window, e ) + gTextPopupBody.offsetWidth + 5 > FMCGetClientWidth( window, false ) )
  618.         {
  619.             gTextPopupBody.style.left = FMCGetScrollLeft( window ) + FMCGetClientWidth( window, false ) - gTextPopupBody.offsetWidth - 5 + "px";
  620.         }
  621.         else
  622.         {
  623.             gTextPopupBody.style.left = FMCGetPageX( window, e ) + "px";
  624.         }
  625.         
  626.         // Set up background
  627.         
  628.         gTextPopupBodyBG = document.createElement( "span" );
  629.         gTextPopupBodyBG.className = "MCTextPopupBodyBG";
  630.         gTextPopupBodyBG.style.top = parseInt( gTextPopupBody.style.top ) + 5 + "px";
  631.         gTextPopupBodyBG.style.left = parseInt( gTextPopupBody.style.left ) + 5 + "px";
  632.         
  633.         FMCSetTextPopupDimensions();
  634.         
  635.         gTextPopupBody.parentNode.appendChild( gTextPopupBodyBG );
  636.         window.onresize = FMCSetTextPopupDimensions;
  637.         gPopupObj = gTextPopupBody;
  638.         gPopupBGObj = gTextPopupBodyBG;
  639.         gJustPopped = true;
  640.         
  641.         //
  642.         
  643.         gFadeID = setInterval( "FMCFade()", 10 );
  644.     }
  645. }
  646.  
  647. function FMCSetTextPopupSize( popupNode )
  648. {
  649.     var clientWidth     = FMCGetClientWidth( window, false );
  650.     var clientHeight    = FMCGetClientHeight( window, false );
  651.     var stepSize        = 10;
  652.     var hwRatio         = clientHeight / clientWidth;
  653.     var maxX            = clientWidth * 0.618034;
  654.     var i               = 0;
  655.     
  656.     while ( true )
  657.     {
  658.         popupNode.style.width = maxX - (i * stepSize) + "px";
  659.         popupNode.style.height = (maxX - (i * stepSize)) * hwRatio + "px";
  660.         
  661.         // "- 2" is to account for borderLeft + borderRight.
  662.         
  663.         if ( popupNode.scrollHeight > popupNode.offsetHeight - 2 || popupNode.scrollWidth > popupNode.offsetWidth - 2 )
  664.         {
  665.             popupNode.style.overflow = "hidden";    // Since scrollbars are now present, temporarily remove them before enlarging the node or else they'll still be present
  666.             popupNode.style.overflow = "auto";      // Allow scrollbars again.
  667.             
  668.             popupNode.style.width = maxX - ((i - 1) * stepSize) + "px";
  669.             popupNode.style.height = (maxX - ((i - 1) * stepSize)) * hwRatio + "px";
  670.             
  671.             break;
  672.         }
  673.         
  674.         i++;
  675.     }
  676.     
  677.     // Debug
  678.     //window.status = popupNode.offsetWidth + ", " + popupNode.scrollWidth + ", " + popupNode.offsetHeight + ", " + popupNode.scrollHeight;
  679. }
  680.  
  681. function FMCToggler( node )
  682. {
  683.     // Don't continue if something is already popped up
  684.     
  685.     if ( gPopupObj )
  686.     {
  687.         return;
  688.     }
  689.     
  690.     // Toggle the icon
  691.     
  692.     var imgNodes    = node.getElementsByTagName( "img" );
  693.     
  694.     for ( var i = 0; i < imgNodes.length; i++ )
  695.     {
  696.         var imgNode = imgNodes[i];
  697.         
  698.         if ( FMCContainsClassRoot( imgNode.className, "MCTogglerIcon" ) )
  699.         {
  700.             FMCImageSwap( imgNode, "swap" );
  701.             
  702.             break;
  703.         }
  704.     }
  705.     
  706.     // Toggle all toggler items
  707.     
  708.     var targets = FMCGetMCAttribute( node, "MadCap:targets" ).split( ";" );
  709.     
  710.     for ( var i = 0; i < targets.length; i++ )
  711.     {
  712.         var nodes   = FMCGetElementsByAttribute( document, "MadCap:targetName", targets[i] );
  713.         
  714.         for ( var j = 0; j < nodes.length; j++ )
  715.         {
  716.             if ( nodes[j].style.display == "none" )
  717.             {
  718.                 nodes[j].style.display = "";
  719.                 
  720.                 FMCUnhide( window, nodes[j] );
  721.             }
  722.             else
  723.             {
  724.                 nodes[j].style.display = "none";
  725.             }
  726.         }
  727.     }
  728. }
  729.  
  730. function FMCSetTextPopupDimensions()
  731. {
  732.     gTextPopupBodyBG.style.width = gTextPopupBody.offsetWidth + "px";
  733.     gTextPopupBodyBG.style.height = gTextPopupBody.offsetHeight + "px";
  734. }
  735.  
  736. function FMCFade()
  737. {
  738.     var finished    = false;
  739.     
  740.     if ( gPopupObj.filters )
  741.     {
  742.         var opacity    = gPopupObj.style.filter;
  743.         
  744.         if ( opacity == "" )
  745.         {
  746.             opacity = "alpha( opacity = 0 )";
  747.         }
  748.         
  749.         gPopupObj.style.filter = "alpha( opacity = " + (parseInt( opacity.substring( 17, opacity.length - 2 ) ) + 10) + " )";
  750.         
  751.         if ( gPopupBGObj )
  752.         {
  753.             opacity = gPopupBGObj.style.filter;
  754.             
  755.             if ( opacity == "" )
  756.             {
  757.                 opacity = "alpha( opacity = 0 )";
  758.             }
  759.             
  760.             gPopupBGObj.style.filter = "alpha( opacity = " + (parseInt( opacity.substring( 17, opacity.length - 2 ) ) + 5) + " )";
  761.         }
  762.         
  763.         if ( gPopupObj.style.filter == "alpha( opacity = 100 )" )
  764.         {
  765.             finished = true;
  766.         }
  767.     }
  768.     else if ( gPopupObj.style.MozOpacity != null )
  769.     {
  770.         var opacity    = gPopupObj.style.MozOpacity;
  771.         
  772.         if ( opacity == "" )
  773.         {
  774.             opacity = "0.0";
  775.         }
  776.         
  777.         gPopupObj.style.MozOpacity = parseFloat( opacity ) + 0.11;
  778.         
  779.         if ( gPopupBGObj )
  780.         {
  781.             opacity = gPopupBGObj.style.MozOpacity;
  782.             
  783.             if ( opacity == "" )
  784.             {
  785.                 opacity = "0.0";
  786.             }
  787.             
  788.             gPopupBGObj.style.MozOpacity = parseFloat( opacity ) + 0.05;
  789.         }
  790.         
  791.         if ( parseFloat( gPopupObj.style.MozOpacity ) == 0.99 )
  792.         {
  793.             finished = true;
  794.         }
  795.     }
  796.     
  797.     if ( finished )
  798.     {
  799.         clearInterval( gFadeID );
  800.         gFadeID = 0;
  801.     }
  802. }
  803.  
  804. var MCFader    = new function()
  805. {
  806.     // Public methods
  807.  
  808.     this.FadeIn    = function( node, nodeBG )
  809.     {
  810.         var interval    = 0;
  811.         var funcIndex    = -1;
  812.  
  813.         FMCSetOpacity( node, 0 );
  814.         FMCSetOpacity( nodeBG, 0 );
  815.  
  816.         function DoFadeIn()
  817.         {
  818.             var opacity    = FMCGetOpacity( node );
  819.             
  820.             if ( opacity == 0 )
  821.             {
  822.                 function OnClickDocument()
  823.                 {
  824.                     node.parentNode.removeChild( node );
  825.                     nodeBG.parentNode.removeChild( nodeBG );
  826.                     
  827.                     gDocumentOnclickFuncs.splice( funcIndex, 1 );
  828.                 }
  829.                 
  830.                 funcIndex = gDocumentOnclickFuncs.push( OnClickDocument ) - 1;
  831.             }
  832.             
  833.             opacity += 10;
  834.  
  835.             FMCSetOpacity( node, opacity );
  836.             FMCSetOpacity( nodeBG, opacity / 2 );
  837.  
  838.             if ( opacity >= 100 )
  839.             {
  840.                 clearInterval( interval );
  841.             }
  842.         }
  843.  
  844.         interval = setInterval( DoFadeIn, 10 );
  845.     };
  846. }
  847.